package com.dz.Incubator.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dz.Incubator.config.ReturnCode;
import com.dz.Incubator.dto.BindDto;
import com.dz.Incubator.dto.PcLoginDto;
import com.dz.Incubator.entity.InvokeResult;
import com.dz.Incubator.properties.WechatGetUserInfoUtil;
import com.dz.Incubator.properties.WeiXinUserInfo;
import com.dz.Incubator.properties.WxMiniProperties;
import com.dz.Incubator.service.SysUserService;
import com.dz.Incubator.entity.SysUserEntity;
import com.dz.Incubator.utils.VerifyCodeGen;
import com.dz.Incubator.utils.sms.NewSMSUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.models.auth.In;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.validation.Valid;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/api/a/zx")
@Api(tags = {"登录"})
public class WeChatController {

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private WxMiniProperties wxMiniProperties;

    @Autowired
    private RedisTemplate redisTemplate;


    @GetMapping("/weChat/login")
    public InvokeResult login(String code) {
        String url = wxMiniProperties.getInterfaceUrl() + "/sns/jscode2session?appid="
                + wxMiniProperties.getAppId() + "&secret=" + wxMiniProperties.getAppSecret()
                + "&js_code=" + code + "&grant_type=authorization_code";
        JSONObject message;
        try {
            RestTemplate restTemplate = new RestTemplate();
            String response = restTemplate.getForObject(url, String.class);
            message = JSON.parseObject(response);

            String sessionKey = (String) message.get("session_key");
            redisTemplate.opsForValue().set(code, sessionKey, 60 * 60, TimeUnit.SECONDS);
            SysUserEntity userEntity = sysUserService.findByOpenId(message.getString("openid"));
            if (userEntity != null) {
                return InvokeResult.success(userEntity);
            }
            return InvokeResult.success(false);
        } catch (Exception e) {
            e.printStackTrace();
            message = new JSONObject();
        }
        return InvokeResult.success(false);
    }

    /**
     * 通过encryptedData,sessionKey,iv获得解密信息, 拥有用户丰富的信息, 包含openid,unionid,昵称等
     */
    @PostMapping("/weChat/bindPhone")
    public InvokeResult decryptWxData(@Valid @RequestBody BindDto dto) throws Exception {
        if (!verify(dto.getPhoneNumber(), dto.getVerifyCode())) {
            InvokeResult.failure("验证码错误");
        }
        Object sessionKey = redisTemplate.opsForValue().get(dto.getCode());
        if (sessionKey == null) {
            return InvokeResult.failure("请重新授权");
        }
        //解密获取用户信息
        JSONObject userInfoJSON = WechatGetUserInfoUtil.getUserInfo(dto.getEncryptedData(), sessionKey.toString(), dto.getIv());

        if (userInfoJSON != null) {
            String s = userInfoJSON.toJSONString();
            WeiXinUserInfo weiXinUserInfo = JSON.parseObject(s, WeiXinUserInfo.class);

            SysUserEntity userEntity = sysUserService.findByOpenId(weiXinUserInfo.getOpenId());
            if (userEntity == null) {
                userEntity = sysUserService.findByPhone(dto.getPhoneNumber());
                if (userEntity == null) {
                    userEntity = new SysUserEntity();
                    userEntity.setAddress(weiXinUserInfo.getCountry() + weiXinUserInfo.getCity());
                    userEntity.setWxNickName(weiXinUserInfo.getNickName());
                    userEntity.setOpenId(weiXinUserInfo.getOpenId());
                    userEntity.setSex(Integer.parseInt(weiXinUserInfo.getGender()));
                    userEntity.setHead(weiXinUserInfo.getAvatarUrl());
                    userEntity.setDelTag(0);
                    userEntity.setMobile(dto.getPhoneNumber());
                    userEntity.setCompanyName(dto.getCompanyName());
                    userEntity.setEmail(dto.getEmail());
                    userEntity.setLinkman(dto.getLinkman());
                    userEntity.setQq(dto.getQq());
                    userEntity.setCounselor(dto.getCounselor());
                    userEntity = sysUserService.insert(userEntity);
                } else {
                    userEntity.setAddress(weiXinUserInfo.getCountry() + weiXinUserInfo.getCity());
                    userEntity.setWxNickName(weiXinUserInfo.getNickName());
                    userEntity.setOpenId(weiXinUserInfo.getOpenId());
                    userEntity.setSex(Integer.parseInt(weiXinUserInfo.getGender()));
                    userEntity.setHead(weiXinUserInfo.getAvatarUrl());
                    userEntity.setCompanyName(dto.getCompanyName());
                    userEntity.setEmail(dto.getEmail());
                    userEntity.setLinkman(dto.getLinkman());
                    userEntity.setQq(dto.getQq());
                    userEntity.setCounselor(dto.getCounselor());
                    userEntity = sysUserService.update(userEntity);
                }
            }
            return InvokeResult.success(userEntity);
        }
        return InvokeResult.failure("无法获取用户信息");
    }

    /**
     * PC登录
     *
     * @param dto
     * @return
     */
    @PostMapping("pc/login")
    @ApiOperation(value = "PC登录")
    public InvokeResult pcLogin(@RequestBody PcLoginDto dto) {
        if (verify(dto.getPhoneNumber(), dto.getVerifyCode())) {
            SysUserEntity userEntity = sysUserService.findByPhone(dto.getPhoneNumber());
            if (userEntity == null) {
                return InvokeResult.failure(ReturnCode.USER_NOT_EXST_ERROR.getCode(),dto.getPhoneNumber());
            }
            return InvokeResult.success(userEntity);
        }
        return InvokeResult.failure("验证码错误");
    }

    /**
     * PC绑定个人信息
     *
     * @param dto
     * @return
     */
    @PostMapping("pc/bind")
    public InvokeResult pcBind(@RequestBody BindDto dto) {
        SysUserEntity userEntity = new SysUserEntity();
        userEntity.setMobile(dto.getPhoneNumber());
        userEntity.setCompanyName(dto.getCompanyName());
        userEntity.setEmail(dto.getEmail());
        userEntity.setLinkman(dto.getLinkman());
        userEntity.setQq(dto.getQq());
        userEntity.setCounselor(dto.getCounselor());
        sysUserService.insert(userEntity);
        return InvokeResult.success(userEntity);
    }

    /**
     * 获取验证码
     *
     * @param phoneNumber
     * @return
     */
    @GetMapping("verifyCode")
    public InvokeResult verifyCode(String phoneNumber) {
        String verifyCode = VerifyCodeGen.generate();
        //TODO 发送验证码
        redisTemplate.opsForValue().set(phoneNumber, verifyCode, 300, TimeUnit.SECONDS);
        NewSMSUtil.sendMsg(phoneNumber,verifyCode);
        return InvokeResult.success();
    }

    public boolean verify(String phoneNumber, String verifyCode) {
        Object redisCode = redisTemplate.opsForValue().get(phoneNumber);
        if (redisCode != null && redisCode.toString().equals(verifyCode)) {
            redisTemplate.delete(phoneNumber);
            return true;
        }
        return false;
    }

}
